package convert;

import java.util.ArrayList;

import main.Common;
import main.Def;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.jdom.Element;

import config.EConfig;


public class ESheet extends BaseContent
{
	private ArrayList<Head> m_heads;
	private ArrayList<MergeCell> m_mergeCells;
	private ArrayList<EConfig> m_configs;

	private Sheet m_sheet;
	private int m_firstRow;
	
	public ESheet(Sheet sheet, EWorkBook excel)
	{
		super(sheet.getSheetName(), excel);
		m_sheet = sheet;
		m_heads = new ArrayList<>();
		m_mergeCells = new ArrayList<>();
	}
	
	public Sheet getRealSheet()
	{
		return m_sheet;
	}
	
	public ArrayList<EConfig> getConfigs()
	{
		return m_configs;
	}
	
	public void init()
	{
		makeMergeCells();
		makeHead();
		if(m_heads.size() == 0)
		{
			return;
		}
		makeRowContent();
	}
	
	public void initConfig()
	{
		makeMergeCells();
		makeConfig();
	}
	
	private void makeConfig()
	{
		m_configs = new ArrayList<>();
		int len = m_sheet.getLastRowNum() + 1;
		for(int i = 0; i < len; ++i)
		{
			Row row = m_sheet.getRow(i);
			if(!isEmpytRow(row))
			{
				EConfig con = null;
				String name = "";
				int size = row.getLastCellNum();
				for(int j = 0; j < size; ++j)
				{
					Cell c = row.getCell(j);
					String str = ECell.getValue(c);
					if(str.length() != 0)
					{
						if(con == null)
						{
							con = new EConfig(str);
							name = str;
						}
						else
						{
							con.addValue(str);
						}
					}
				}
				if(con.getType() != null)
				{
					m_configs.add(con);
				}
				else {
					Common.print("unknown config " + name);
				}
			}
		}
	}
	
	private void makeMergeCells()
	{
		int len = m_sheet.getNumMergedRegions();
		for(int i = 0; i < len; ++i)
		{
			MergeCell mc = new MergeCell(m_sheet.getMergedRegion(i));
			m_mergeCells.add(mc);
		}
	}
	
	private boolean isEmpytRow(Row row)
	{
		if(row == null)
		{
			return true;
		}
		int len = row.getLastCellNum();
		for(int i = 0; i <= len; ++i)
		{
			Cell cell = row.getCell(i);
			if(cell != null && ECell.getValue(cell).length() > 0)
			{
				return false;
			}
		}
		return true;
	}
	private void makeHead()
	{
		Row firstRow = null;
		int len = m_sheet.getLastRowNum() + 1;
		for(int i = 0; i < len; ++i)
		{
			firstRow = m_sheet.getRow(i);
			if(!isEmpytRow(firstRow))
			{
				m_firstRow = i;
				break;
			}
		}
		if(firstRow == null)
		{
			Common.print(m_name + " is empty");
			return;
		}
		len = firstRow.getLastCellNum();
		for(int i = 0; i < len; ++i)
		{
			Cell cell = firstRow.getCell(i);
			if(cell != null)
			{
				Head head = new Head(firstRow, i);
				MergeCell merge = isMergeCell(m_firstRow, i);
				if(merge != null)
				{
					i = merge.getX2();
				}
				head.setEnd(i);
				if(hasHead(head.getName()) != null)
				{
					Common.print("duplicate head name " + head.getName());
				}
				m_heads.add(head);
			}
		}
	}

	private void makeRowContent()
	{
		int len = m_sheet.getLastRowNum() + 1;
		for(int i = m_firstRow + 1; i < len; ++i)
		{
			Row row = m_sheet.getRow(i);
			if(!isEmpytRow(row))
			{
				ERow er = new ERow(this, i);
				MergeCell merge = isMergeCell(i, 0);
				if(merge != null)
				{
					i = merge.getY2();
				}
				er.setEnd(i);
				er.init(m_heads);
				addChild(er);
			}
		}
	}
	
	public Head getHead(int index)
	{
		return m_heads.get(index);
	}
	
	public Head hasHead(String name)
	{
		for(Head temp: m_heads)
		{
			if(name.compareTo(temp.getName()) == 0)
			{
				return temp;
			}
		}
		return null;
	}
	
	public int getColumnContentNumber()
	{
		return m_heads.size();
	}
	
	public int getFirstRow()
	{
		return m_firstRow;
	}
	
	public Cell getCellAt(int row, int column)
	{
		Row r = m_sheet.getRow(row);
		if(r == null)
		{
			return null;
		}
		return r.getCell(column);
	}
	
	/*
	
	public void fromXml(XmlNode node) throws ErrorException
	{
		XmlNode hNode = node.getChild(0);
		int size = hNode.getChildNumber();
		int len = size;
		m_sheet.addRow(0, len);
		for(int i = 0; i < size; ++i)
		{
			m_sheet.setValue(i, 0, hNode.getChild(i).getAttribute(Def.VALUE));
		}
		size = node.getChildNumber();
		int start = 1;
		for(int i = 0; i < size; ++i)
		{
			XmlNode temp = node.getChild(i);
			String name = temp.getAttribute(Def.VALUE);
			int max = getRowCount(temp);
			for(int j = 0; j < max; ++j)
			{
				m_sheet.addRow(start + j, len);
			}
			m_sheet.setMerge(0, start, 1, max);
			m_sheet.setValue(0, start, name);
			ERow rc = new ERow(this, start);
			start += max;
			rc.setEnd(start);
			rc.fromXml(temp);
		}
	}
	
	private int getRowCount(XmlNode node)
	{
		int max = 0;
		for(int i = 0, size = node.getChildNumber(); i < size; ++i)
		{
			int num = node.getChild(i).getChildNumber();
			if(num > max)
			{
				max = num;
			}
		}
		return max;
	}*/
	
	public MergeCell isMergeCell(int row, int column)
	{
		for(MergeCell merge: m_mergeCells)
		{
			if(merge.isMergeCell(row, column))
			{
				return merge;
			}
		}
		return null;
	}
	
	public void toXml(Element node)
	{
		Element sheet = null;
		if(EConfig.m_isSimpleFormat)
		{
			sheet = new Element(m_name);
		}
		else
		{
			sheet = new Element(Def.SHEET);
			sheet.setAttribute(Def.NAME, m_name);
		}
		if(m_children != null)
		{
			for(BaseContent bc: m_children)
			{
				ERow rc = (ERow)bc;
				rc.toXml(sheet);
			}
		}
		node.addContent(sheet);
	}
}


